#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <cassert>
#include <fstream>
#include <cstdlib>
#include <jsoncpp/json/json.h>
#include <mysql/mysql.h>
#include "../comm/util.hpp"
#include "../comm/log.hpp"


// 使用MySQL加载题目

namespace ns_model
{
    using namespace ns_log;
    struct Question
    {
        std::string id; // 题目编号
        std::string name; // 题目名称
        std::string level; // 题目难度
        int cpu_limit; // 时间限制（单位：s）
        int mem_limit; // 内存限制（单位：KB）
        std::string desc; // 文件描述
        std::string header; // 文件头
        std::string tail; // 文件尾
    };

    class Model
    {
    public:
        Model()
        {}

        ~Model()
        {}

    public:
        bool LoadOneQuestion(const std::string& id, Question* q)
        {
            std::string sql = "select * from " + table_name + " where id=" + id;
            
            std::vector<Question> v;
            if(MysqlQuery(sql, &v) == false)
            {
                LOG(WORNING) << "LoadOneQuestion filed" << "\n";
                return false;
            }
            if(v.size() != 1)
            {
                LOG(WORNING) << "Question format error" << "\n";
            }
            *q = v[0];

            LOG(INFO) << "题目:" << q->id << " 加载成功\n";
            return true;
        }

        bool LoadAllQuestion(std::vector<Question>* v)
        {
            std::string sql = "select * from " + table_name;

            if(MysqlQuery(sql, v) == false)
            {
                LOG(WORNING) << "LoadAllQuestion filed" << "\n";
                return false;
            }

            LOG(INFO) << "成功加载所有题目\n";
            return true;
        }
    private:
        bool MysqlQuery(const std::string& sql, std::vector<Question>* v)
        {
            MYSQL* pmq = mysql_init(nullptr); // 初始化
            if(nullptr == pmq)
            {
                LOG(FATAL) << "mysql init failed" << "\n";
                return false;
            }

            if(mysql_real_connect(pmq, host.c_str(), user.c_str(), password.c_str(), database_name.c_str(), port, nullptr, 0) == nullptr)
            {
                LOG(FATAL) << "mysql connect failed" << "\n";
                return false;
            }

            mysql_set_character_set(pmq, "utf8");
            LOG(INFO) << "连接数据库成功!" << "\n";

            if(mysql_query(pmq, sql.c_str()) != 0) // 查询
            {
                LOG(FATAL) << "mysql query failed" << "\n";
                return false;
            }
            MYSQL_RES* res = mysql_store_result(pmq); // 获取结果

            int rows = mysql_num_rows(res); // 结果行数
            int cols = mysql_num_fields(res); // 结果列数

            Question q;
            for(int i = 0; i < rows; i++)
            {
                MYSQL_ROW row = mysql_fetch_row(res); // 获取每一行信息
                q.id = row[0];
                q.name = row[1];
                q.level = row[2];
                q.desc = row[3];
                q.header = row[4];
                q.tail = row[5];
                q.cpu_limit = atoi(row[6]);
                q.mem_limit = atoi(row[7]);
                v->push_back(q);
            }

            // free(res);
            mysql_close(pmq); // 关闭数据库
            return true;
        }

    private:
        const std::string table_name = "oj_questions"; // MySQL表名称
        const std::string host = "127.0.0.1"; // ip
        const std::string user = "oj_client"; // 用户名
        const std::string password = "10109@Wyq"; // 用户名
        const std::string database_name = "oj"; // MySQL数据库名称
        const int port = 3306; // 端口
    };
}